"""
查询执行器
执行SQL查询计划，处理各种SQL操作
"""

from typing import List, Dict, Any, Optional, Tuple
from storage.storage_manager import StorageManager
from storage.buffer_manager import BufferManager
from storage.page_manager import PageManager, Record

class QueryExecutor:
    """查询执行器"""
    
    def __init__(self, storage_manager: StorageManager, buffer_manager: BufferManager):
        """初始化查询执行器"""
        self.storage_manager = storage_manager
        self.buffer_manager = buffer_manager
        self.page_manager = PageManager(storage_manager, buffer_manager)
    
    def execute(self, query_plan: Dict[str, Any]) -> Any:
        """执行查询计划"""
        query_type = query_plan['type']
        
        if query_type == 'CREATE_TABLE':
            return self.execute_create_table(query_plan)
        elif query_type == 'INSERT':
            return self.execute_insert(query_plan)
        elif query_type == 'SELECT':
            return self.execute_select(query_plan)
        elif query_type == 'UPDATE':
            return self.execute_update(query_plan)
        elif query_type == 'DELETE':
            return self.execute_delete(query_plan)
        elif query_type == 'DROP_TABLE':
            return self.execute_drop_table(query_plan)
        else:
            raise Exception(f"不支持的查询类型: {query_type}")
    
    def execute_create_table(self, query_plan: Dict[str, Any]) -> str:
        """执行CREATE TABLE语句"""
        table_name = query_plan['table_name']
        schema = query_plan['schema']
        
        success = self.storage_manager.create_table(table_name, schema)
        if success:
            return f"表 '{table_name}' 创建成功"
        else:
            raise Exception(f"创建表 '{table_name}' 失败")
    
    def execute_insert(self, query_plan: Dict[str, Any]) -> str:
        """执行INSERT语句"""
        table_name = query_plan['table_name']
        values = query_plan['values']
        columns = query_plan['columns']
        
        # 构建记录数据
        record_data = {}
        for col_name, value in zip(columns, values):
            record_data[col_name] = value
        
        # 获取表结构
        schema = self.storage_manager.get_schema(table_name)
        if not schema:
            raise Exception(f"表 '{table_name}' 不存在")
        
        # 创建记录
        record = Record(record_data, schema)
        
        # 插入记录
        success = self.page_manager.insert_record(table_name, record)
        if success:
            return f"成功插入1条记录到表 '{table_name}'"
        else:
            raise Exception(f"插入记录到表 '{table_name}' 失败")
    
    def execute_select(self, query_plan: Dict[str, Any]) -> List[Dict[str, Any]]:
        """执行SELECT语句"""
        table_name = query_plan['table_name']
        columns = query_plan['columns']
        where_condition = query_plan.get('where')
        schema = query_plan['schema']
        
        # 扫描所有记录
        all_records = self.page_manager.scan_records(table_name)
        
        # 应用WHERE条件过滤
        filtered_records = []
        for page_id, record_id, record in all_records:
            if self._evaluate_condition(where_condition, record.data, schema):
                filtered_records.append(record)
        
        # 选择列
        result = []
        for record in filtered_records:
            if columns == '*':
                result.append(record.data)
            else:
                selected_data = {}
                for col in columns:
                    if col in record.data:
                        selected_data[col] = record.data[col]
                result.append(selected_data)
        
        return result
    
    def execute_update(self, query_plan: Dict[str, Any]) -> str:
        """执行UPDATE语句"""
        table_name = query_plan['table_name']
        assignments = query_plan['assignments']
        where_condition = query_plan.get('where')
        schema = query_plan['schema']
        
        # 扫描所有记录
        all_records = self.page_manager.scan_records(table_name)
        
        updated_count = 0
        for page_id, record_id, record in all_records:
            if self._evaluate_condition(where_condition, record.data, schema):
                # 构建新数据
                new_data = record.data.copy()
                for assignment in assignments:
                    col_name = assignment['column']
                    new_value = assignment['value']
                    new_data[col_name] = new_value
                
                # 更新记录
                success = self.page_manager.update_record(table_name, page_id, record_id, new_data)
                if success:
                    updated_count += 1
        
        return f"成功更新 {updated_count} 条记录"
    
    def execute_delete(self, query_plan: Dict[str, Any]) -> str:
        """执行DELETE语句"""
        table_name = query_plan['table_name']
        where_condition = query_plan.get('where')
        schema = query_plan['schema']
        
        # 扫描所有记录
        all_records = self.page_manager.scan_records(table_name)
        
        deleted_count = 0
        for page_id, record_id, record in all_records:
            if self._evaluate_condition(where_condition, record.data, schema):
                # 删除记录
                success = self.page_manager.delete_record(table_name, page_id, record_id)
                if success:
                    deleted_count += 1
        
        return f"成功删除 {deleted_count} 条记录"
    
    def execute_drop_table(self, query_plan: Dict[str, Any]) -> str:
        """执行DROP TABLE语句"""
        table_name = query_plan['table_name']
        
        success = self.storage_manager.drop_table(table_name)
        if success:
            return f"表 '{table_name}' 删除成功"
        else:
            raise Exception(f"删除表 '{table_name}' 失败")
    
    def _evaluate_condition(self, condition: Optional[Dict[str, Any]], record_data: Dict[str, Any], schema: Dict[str, Any]) -> bool:
        """评估WHERE条件"""
        if condition is None:
            return True
        
        if not isinstance(condition, dict):
            return False
        
        if condition['type'] == 'AND':
            left_result = self._evaluate_condition(condition['left'], record_data, schema)
            right_result = self._evaluate_condition(condition['right'], record_data, schema)
            return left_result and right_result
        
        elif condition['type'] == 'OR':
            left_result = self._evaluate_condition(condition['left'], record_data, schema)
            right_result = self._evaluate_condition(condition['right'], record_data, schema)
            return left_result or right_result
        
        elif condition['type'] == 'NOT':
            operand_result = self._evaluate_condition(condition['operand'], record_data, schema)
            return not operand_result
        
        elif condition['type'] in ['EQ', 'NE', 'LT', 'LE', 'GT', 'GE']:
            left_value = self._evaluate_expression(condition['left'], record_data, schema)
            right_value = self._evaluate_expression(condition['right'], record_data, schema)
            
            # 处理None值
            if left_value is None or right_value is None:
                return False
            
            if condition['type'] == 'EQ':
                return left_value == right_value
            elif condition['type'] == 'NE':
                return left_value != right_value
            elif condition['type'] == 'LT':
                return left_value < right_value
            elif condition['type'] == 'LE':
                return left_value <= right_value
            elif condition['type'] == 'GT':
                return left_value > right_value
            elif condition['type'] == 'GE':
                return left_value >= right_value
        
        return False
    
    def _evaluate_expression(self, expr: Any, record_data: Dict[str, Any], schema: Dict[str, Any]) -> Any:
        """评估表达式"""
        if isinstance(expr, dict) and expr.get('type') == 'binary_op':
            left_value = self._evaluate_expression(expr['left'], record_data, schema)
            right_value = self._evaluate_expression(expr['right'], record_data, schema)
            
            operator = expr['operator']
            if operator == '+':
                return left_value + right_value
            elif operator == '-':
                return left_value - right_value
            elif operator == '*':
                return left_value * right_value
            elif operator == '/':
                return left_value / right_value if right_value != 0 else None
        
        elif isinstance(expr, str):
            # 列引用
            if expr in record_data:
                return record_data[expr]
            else:
                # 可能是字面量
                try:
                    return int(expr)
                except ValueError:
                    try:
                        return float(expr)
                    except ValueError:
                        return expr
        
        elif isinstance(expr, (int, float, str)):
            # 直接的字面量
            return expr
        
        return expr
    
    def get_table_info(self, table_name: str) -> Optional[Dict[str, Any]]:
        """获取表信息"""
        return self.storage_manager.get_table_info(table_name)
    
    def list_tables(self) -> List[str]:
        """列出所有表"""
        return self.storage_manager.list_tables()
    
    def get_record_count(self, table_name: str) -> int:
        """获取表的记录数"""
        return self.storage_manager.get_record_count(table_name)

# 测试函数
if __name__ == "__main__":
    from storage.storage_manager import StorageManager
    from storage.buffer_manager import BufferManager
    
    # 创建管理器
    storage = StorageManager("test_data")
    buffer_manager = BufferManager(10)
    buffer_manager.set_storage_manager(storage)
    executor = QueryExecutor(storage, buffer_manager)
    
    # 测试CREATE TABLE
    create_plan = {
        'type': 'CREATE_TABLE',
        'table_name': 'users',
        'schema': {
            'columns': {
                'id': {'type': {'type': 'int'}},
                'name': {'type': {'type': 'varchar', 'length': 50}},
                'age': {'type': {'type': 'int'}}
            },
            'primary_key': 'id'
        }
    }
    
    print("创建表...")
    result = executor.execute(create_plan)
    print(result)
    
    # 测试INSERT
    insert_plan = {
        'type': 'INSERT',
        'table_name': 'users',
        'values': [1, 'Alice', 25],
        'columns': ['id', 'name', 'age']
    }
    
    print("\n插入记录...")
    result = executor.execute(insert_plan)
    print(result)
    
    # 测试SELECT
    select_plan = {
        'type': 'SELECT',
        'table_name': 'users',
        'columns': '*',
        'where': {
            'type': 'GT',
            'left': 'age',
            'right': 20
        },
        'schema': create_plan['schema']
    }
    
    print("\n查询记录...")
    result = executor.execute(select_plan)
    print(f"查询结果: {result}")
    
    # 清理
    drop_plan = {
        'type': 'DROP_TABLE',
        'table_name': 'users'
    }
    
    print("\n删除表...")
    result = executor.execute(drop_plan)
    print(result)
    
    buffer_manager.clear()
